// ==================================================================================
// Shared Genomics Project MPI Codebase
// Version 1.0 30/04/2010
//
// (c) 2010 University of Manchester all rights reserved
//
// This file is distributed under the GNU General Public License, Version 2.  
// Please see the file COPYING.txt for more details
// ==================================================================================

#ifndef _MAPFILE_H_
#define _MAPFILE_H_

#include "options.h"
#include "types.h"
#include "chromosomes.h"
#include "csnp.h"

#ifdef __cplusplus
extern "C" {
#endif

/*!
\file
\ingroup	gio
\brief		SNP-Major Genomic Data-set (PLINK)
\details
	This header provides methods to store allelic data of an entire genomic data-set and 
	is based on the data storage logic of PLINK.<br>
	The \ref mapfile structure is essentially a 1-D array of SNPs (see \ref mapfile::locus)
	and a 2-D array of allelic data for each person in the sample cohort (see \ref mapfile::SNP, \ref csnp::one, \ref csnp::two).<br>
	The \ref mapfile  structure stores information read from a PLINK-compatible text file 
	and is not used in the statistical calculation codes.
*/

/*! \brief	SNP-Major Genomic Data-set (PLINK) */
struct mapfile {
	/*! \brief the Locus list of the data-set */
	struct locus **locus;

	/*! \brief Size of the locus array */
	int nLocus; // Active elements

	/*! \brief Amount of storage allocated to the locus array */
	int locus_available;

	/*! \brief SNP-Major Allelic data array */
	struct csnp** SNP;

	/*! \brief Size of the SNP array */
	int nSNP;
};

/*! 
\brief Initialise a \ref mapfile structure.
\details All dynamic arrays set to NULL and counters are zeroed.
\param [in,out] m Mapfile structure to initialise
\returns 1 on success, 0 on failure
*/
int mapfile_init(struct mapfile *m);

/*! 
\brief Read a PLINK map file (SNP list)
\details
	Function reads a text PLINK map file and stores the information in \ref mapfile::locus array.<br>
	The input filename is bound to \ref selected_options::szMapFileName.<br>
\param [in,out] m mapfile structure to store the locus/SNP list
\param [in] ops Location of the input file
\param [in] chromos The chromosomal model
\returns 1 on success, 0 on failure
*/
int mapfile_read(struct mapfile *m, struct selected_options *ops, struct chromosomes *chromos);

/*! 
\brief Free the dynamic arrays bound to a \ref mapfile structure.
\details All dynamic arrays freed and counters set to zero.
\param [in,out] m mapfile structure
\returns 1 on success, 0 on failure
*/
int mapfile_free_attributes(struct mapfile *m);

/*! 
\brief Allocates storage to \ref mapfile::locus .
\param [in] size No. size of the locus array
\param [in,out] m mapfile structure
\returns 1 on success, 0 on failure
*/
int mapfile_alloc_locus(int size, struct mapfile *m);

/*! 
\brief Re-allocates storage to mapfile::locus if the array needs to grow.
\param [in] size No. size of the locus array
\param [in,out] m mapfile structure
\returns 1 on success, 0 on failure
*/
int mapfile_realloc_locus(int size, struct mapfile *m);

/*!
\brief Inserts/appends a locus to the mapfile::locus array.
\details 
	The mapfile::locus will grow as necessary to accodomate extra SNPs 
	if the initial memory allocation is filled.
\param [in,out] value Locus to append to the array
\param [in,out] m mapfile structure
\returns 1 on success, 0 on failure
*/
int mapfile_insert_locus(struct locus *value, struct mapfile *m);

/*! 
\brief Create an 'initialised' \ref mapfile structure. 
\return \ref mapfile structure or NULL on failure.
*/
struct mapfile* mapfile_create();

/*!
\brief Allocate the \ref mapfile::SNP array.
\param [in] nSNPs No. of SNPs/loci in a genomic data-set
\param [in] nSamples No. of samples/people in a genomic data-set
\param [in,out] m mapfile structure
\returns 1 on success, 0 on failure
*/
int mapfile_alloc_SNP(int nSNPs, int nSamples, struct mapfile *m);

/*!
\brief Copy a PLINK map file to a local directory and read.
\details
	The input filename is bound to \ref selected_options::szMapFileName.
\param [in,out] m mapfile structure
\param [in] ops Input file location
\param [in] chromos chromosomal model
\param [in] rank Local processor rank
\returns 1 on success, 0 on failure
*/
int mapfile_copy_and_read(struct mapfile *m, struct selected_options *ops, struct chromosomes *chromos, int rank);

#ifdef __cplusplus
}
#endif

#endif // _MAPFILE_H_
